package cn.hackcloud.netty.basic.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class TimeClientHandle implements Runnable {
	private Selector selector;
	private SocketChannel socketChannel;
	private volatile boolean stop;

	public TimeClientHandle() {
		super();
		try {
			selector = Selector.open();
			socketChannel = SocketChannel.open();
			socketChannel.configureBlocking(false);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	@Override
	public void run() {
		try {
			doConnect();
		} catch (IOException e1) {
			e1.printStackTrace();
			System.exit(1);
		}
		while (!stop) {
			try {
				selector.select(1000);
				Set<SelectionKey> keys = selector.selectedKeys();
				Iterator<SelectionKey> iterator = keys.iterator();
				SelectionKey selectionKey = null;
				while (iterator.hasNext()) {
					selectionKey = iterator.next();
					iterator.remove();
					try {
						handleInput(selectionKey);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private void doConnect() throws IOException {
		if (socketChannel.connect(new InetSocketAddress("127.0.0.1", 8888))) {
			socketChannel.register(selector, SelectionKey.OP_READ);
			doWrite(socketChannel);
		} else {
			socketChannel.register(selector, SelectionKey.OP_CONNECT);
		}
	}

	private void handleInput(SelectionKey selectionKey) throws Exception {
		if (selectionKey.isValid()) {
			SocketChannel sc = (SocketChannel) selectionKey.channel();
			if (selectionKey.isConnectable()) {
				if (sc.finishConnect()) {
					sc.register(selector, SelectionKey.OP_READ);
					doWrite(sc);
				} else {
					System.exit(1);
				}
			}
			if (selectionKey.isReadable()) {
				ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
				int read = sc.read(byteBuffer);
				if (read > 0) {
					byteBuffer.flip();
					byte[] bytes = new byte[byteBuffer.remaining()];
					byteBuffer.get(bytes);
					String body = new String(bytes, "UTF-8");
					System.out.println("NOW IS " + body);
					this.stop = true;
				} else if (read < 0) {
					selectionKey.cancel();
					sc.close();
				}
			}
		}

	}

	private void doWrite(SocketChannel sc) throws IOException {
		byte[] req = "TIME".getBytes();
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		byteBuffer.put(req);
		byteBuffer.flip();
		sc.write(byteBuffer);
		if (!byteBuffer.hasRemaining()) {
			System.out.println("send server order 2 successed.");
		}
	}

}
